/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ekuma.impexp;

import cn.ekuma.impexp.engine.csv.CSVEngine;
import cn.ekuma.impexp.model.AbstractImpExpTableDefinition;
import cn.ekuma.impexp.model.ImpExpRowDefinition;
import cn.ekuma.impexp.model.ImpExpTableDefinition;
import cn.ekuma.impexp.processor.ExportObjectConverProcessor;
import cn.ekuma.impexp.processor.ImportObjectConverProcessor;
import cn.ekuma.impexp.processor.ImportObjectStateProcessor;
import com.openbravo.data.basic.BasicException;
import com.openbravo.data.loader.SentenceExec;
import com.openbravo.data.loader.StaticSentence;
import com.openbravo.data.loader.TableDefinition;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Administrator
 */
public class ImpExpManager {

    static Map<String, List<TableDefinition>> defaultTableGroups = new HashMap<String, List<TableDefinition>>();
    static TableDefinitionTreeNode tableTreeRoot = new TableDefinitionTreeNode();
    static Map<String, List<ImpExpTableTrigger>> tableTriggers = new HashMap<String, List<ImpExpTableTrigger>>();
    private static Map<String, Class> enginesMap = new HashMap();//执行器注册类表
    ImpExpConfig config;
    List<AbstractImpExpTableDefinition> impExpTableDefinition= new ArrayList<AbstractImpExpTableDefinition>();

    ImportObjectConverProcessor defaultImportProcessor = new ImportObjectConverProcessor(this);
    ExportObjectConverProcessor defaultExportProcessor = new ExportObjectConverProcessor(this);
    ImportObjectStateProcessor  defaultImportStateProcessor=new ImportObjectStateProcessor(this);

    private static Map<String, FieldConverse> fieldConverses = new HashMap();
    private static Map<String, FieldGenerator> fieldGenerator = new HashMap();
    
    
    public static final ImpExpManager INSTANCE=new ImpExpManager();

    public static void regist(String engineName, Class engineClass) {
        enginesMap.put(engineName, engineClass);
    }
    
    public ImpExpManager(){
    	enginesMap.put(CSVEngine.PROPERTY_prefix, CSVEngine.class);
    }
    

    public void init(ImpExpConfig config) {
        if (config == null) {
            config = new ImpExpConfig();
        }
        this.config = config;
        buildImpExpTableDefinitions(tableTreeRoot);
    }


    private void buildImpExpTableDefinitions(TableDefinitionTreeNode node) {
        for (TableDefinitionTreeNode cNode : node.getNodes()) {
            buildImpExpTableDefinitions(cNode);
        }
        for (TableDefinition table : node.getTables()) {
            impExpTableDefinition.add(new ImpExpTableDefinition(table));
        }
    }

    public void doImport(String type) throws BasicException {
    	ImpExpEngine engine;
		try {
			engine = (ImpExpEngine) enginesMap.get(type).newInstance();
		} catch (InstantiationException e) {
			throw new BasicException(e);
		} catch (IllegalAccessException e) {
			throw new BasicException(e);
		}
        engine.init(this);
        for (AbstractImpExpTableDefinition impExpTable : impExpTableDefinition) {
            engine.importTable(impExpTable,null);
            doImportToDb(impExpTable);
        }
    }
    
    public void doImportToDb(AbstractImpExpTableDefinition impExpTable)throws BasicException{
    	defaultImportProcessor.process(impExpTable);
        defaultImportStateProcessor.process(impExpTable);
    	SentenceExec insertSent=impExpTable.getInsertSentence();
        SentenceExec updateSent=impExpTable.getUpdateSentence();
        int rowCount=impExpTable.getRowCount();
        for(int i=0;i<rowCount;i++){
        	ImpExpRowDefinition row=impExpTable.getRow(i);
            if(ImpExpRowDefinition.STATE_Import_Insert==row.getState())
                insertSent.exec(row.getDatas());
            else if(ImpExpRowDefinition.STATE_Import_Update==row.getState())
                updateSent.exec(row.getDatas());
        }
    }

    public void doExport(String type, Date start, Date end) throws BasicException {
        ImpExpEngine engine;
		try {
			engine = (ImpExpEngine) enginesMap.get(type).newInstance();
		} catch (InstantiationException e) {
			throw new BasicException(e);
		} catch (IllegalAccessException e) {
			throw new BasicException(e);
		}
        engine.init(this);
        for (AbstractImpExpTableDefinition impExpTable : impExpTableDefinition) {
            loadDBStoreDate(impExpTable, start, end);
            defaultExportProcessor.process(impExpTable);
            engine.exportTable(impExpTable,null);
        }
    }

    public void doExport(AbstractImpExpTableDefinition impExpTable,String type,String fileName) throws BasicException {
        ImpExpEngine engine;
		try {
			engine = (ImpExpEngine) enginesMap.get(type).newInstance();
		} catch (InstantiationException e) {
			throw new BasicException(e);
		} catch (IllegalAccessException e) {
			throw new BasicException(e);
		}
        engine.init(this);
        defaultExportProcessor.process(impExpTable);
        engine.exportTable(impExpTable,fileName);
    }
    
    
    public void loadDBStoreDate(AbstractImpExpTableDefinition table, Date start, Date end) throws BasicException {
        String sql = table.getListSQL(start, end);
        List data = new StaticSentence(table.getBaseTable().getM_s(), sql,null,table.getSerializerReadBasic()).list();
        for (Object o : data) {
            table.addRow(new ImpExpRowDefinition((Object[]) o));
        }
    }

    public List<AbstractImpExpTableDefinition> getImpExpTableDefinition() {
        return impExpTableDefinition;
    }
    
    public void setImpExpTableDefinition(
			List<AbstractImpExpTableDefinition> impExpTableDefinition) {
		this.impExpTableDefinition = impExpTableDefinition;
	}

	public FieldConverse getTableFieldConverse(String table, String field) {
        String fieldConverseName = config.getTableFieldConverse(table, field);
        return null;
    }

    public FieldGenerator getTableFieldGenerator(String table, String field) {
        String fieldGeneratorName = config.getTableFieldConverse(table, field);
        return null;
    }
    
    public ImpExpManager regeditTable(TableDefinition table){
    	impExpTableDefinition.add(new ImpExpTableDefinition(table));
    	return this;
    }
    
    
    public ImpExpManager regeditTables(List<TableDefinition> tables){
    	for(TableDefinition t:tables)
    	   impExpTableDefinition.add(new ImpExpTableDefinition(t));
    	return this;
    }

	public String getDirStory() {
		return "c:/pos_back/";
	}
	
	public void exportTableDate(AbstractImpExpTableDefinition impExpTable,String type) throws BasicException{
		ImpExpEngine engine;
		try {
			engine = (ImpExpEngine) enginesMap.get(type).newInstance();
		} catch (InstantiationException e) {
			throw new BasicException(e);
		} catch (IllegalAccessException e) {
			throw new BasicException(e);
		}
        engine.init(this);
		engine.exportTable(impExpTable,null);
	}
	
	
	public void importTableDate(AbstractImpExpTableDefinition impExpTable,String type,String fileName) throws BasicException{
		ImpExpEngine engine;
		try {
			engine = (ImpExpEngine) enginesMap.get(type).newInstance();
		} catch (InstantiationException e) {
			throw new BasicException(e);
		} catch (IllegalAccessException e) {
			throw new BasicException(e);
		}
        engine.init(this);
		engine.importTable(impExpTable,fileName);
	}
}
